package com.study.fetch.rk;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.study.fetch.rk.DataDTO.TxzxgData;
import com.study.fetch.ths.RkDemo;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.CompareToBuilder;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhuzi
 * 2025/1/22 17:48
 * 日K涨幅
 */
public class NewYearIncr {
    /**
     * 中证100(sz399903)，沪深300(sh000300)  中证500(sh000905)  中证1000(sh000852)    国证2000(sz399303)  这几个看看吧
     *
     */

    /**
     * 日K
     */
    @Data
    @Accessors(chain = true)
    private class RkDTO {
        private String name;
        private String code;
    }

    static Comparator<TxzxgData> txzxgDataComparator = (a, b) -> new CompareToBuilder().append(a.getBondId(), b.getBondId()).append(a.getDate(), b.getDate()).toComparison();

    @Test
    public void fetch() {
        String path = "/Users/zhuzi/Desktop/pics/A-统计/春节指数3天涨幅";
        ArrayList<RkDTO> rkDTOS = Lists.newArrayList(new RkDTO().setCode("sz399903").setName("中证100"), new RkDTO().setCode("sh000300").setName("沪深300"), new RkDTO().setCode("sh000905").setName("中证500"), new RkDTO().setCode("sh000852").setName("中证1000"), new RkDTO().setCode("sz399303").setName("国证2000"));

        String url = "https://proxy.finance.qq.com/cgi/cgi-bin/stockinfoquery/kline/app/get?added=true&ktype=day&fqtype=qfq&limit=1999&toDate={}&code={}&lang=zh_CN";

        // 腾讯数据
        ArrayList<TxzxgData> txDataList = Lists.newArrayList();
        for (RkDTO rkDTO : rkDTOS) {
            String dateStr = "";
            for (int i = 0; i < 10; i++) {
                String format = StrUtil.format(url, dateStr, rkDTO.getCode());
                System.out.println(format);
                String body = HttpRequest.get(format).timeout(10 * 1000).execute().body();
                JSONObject jsonObject = JSON.parseObject(body);
                List<TxzxgData> list = jsonObject.getJSONObject("data").getList("nodes", TxzxgData.class);
                list.sort(txzxgDataComparator);
                dateStr = list.get(0).getDate().toString();
                list.forEach(ia -> {
                    ia.setBondName(rkDTO.getName());
                    ia.setBondId(rkDTO.getCode());
                });
                txDataList.addAll(list);
            }
        }
        List<TxzxgData> listData = txDataList.stream().distinct().sorted(txzxgDataComparator).collect(Collectors.toList());
        FileUtil.writeUtf8String(JSON.toJSONString(listData), path + "/data.json");
    }

    /**
     * 计算的结果
     */
    @Data
    @Accessors(chain = true)
    private class IncrNewYear {
        private String bondId;
        private String bondName;

        private int days;

        private Integer year;
        private LocalDate firstDate;
        private TxzxgData startData;
        private TxzxgData endData;

        /**
         * 收益率
         */
        private BigDecimal incr;

        public void calcIncr() {
            if (Objects.nonNull(startData) && Objects.nonNull(endData)) {
                BigDecimal syl = RkDemo.syl(endData.getLast(), startData.getLast());
                this.setIncr(syl);
            }
        }
    }

    @Test
    public void calcIncr3() {
        String s = FileUtil.readUtf8String("/Users/zhuzi/Desktop/pics/A-统计/春节指数3天涨幅/data.json");
        List<TxzxgData> txzxgData = JSON.parseArray(s, TxzxgData.class);


        List<String> firstJyrStr = FileUtil.readUtf8Lines("/Users/zhuzi/Desktop/pics/A-统计/春节指数3天涨幅/春节后第一个交易日.txt");

        //交易日Map
        Map<String, LocalDate> jyrMap = firstJyrStr.stream().filter(StringUtils::isNotBlank).collect(Collectors.toMap(ia -> ia.substring(0, 4), ib -> LocalDate.parse(ib)));

        ArrayList<RkDTO> rkDTOS = Lists.newArrayList(new RkDTO().setCode("sz399903").setName("中证100"), new RkDTO().setCode("sh000300").setName("沪深300"), new RkDTO().setCode("sh000905").setName("中证500"), new RkDTO().setCode("sh000852").setName("中证1000"), new RkDTO().setCode("sz399303").setName("国证2000"));


        ArrayList<IncrNewYear> incrNewYearList = Lists.newArrayList();
        for (RkDTO rkDTO : rkDTOS) {
            Map<String, List<TxzxgData>> sh300Map = txzxgData.stream().filter(ia -> ia.getBondId().equals(rkDTO.getCode())).distinct().collect(Collectors.groupingBy(ib -> ib.getDate().getYear() + ""));

            sh300Map.forEach((k, v) -> {
                v.sort(txzxgDataComparator);
                LocalDate date = jyrMap.get(k);

                TxzxgData txdata = v.get(0);
                int indexOf = v.indexOf(new TxzxgData().setBondName(txdata.getBondName()).setBondId(txdata.getBondId()).setDate(date));

                if (indexOf != -1) {
                    TxzxgData startData = v.get(indexOf - 1);
                    TxzxgData endData = v.get(indexOf + 2);
                    incrNewYearList.add(new IncrNewYear().setYear(Integer.parseInt(k)).setFirstDate(date).setBondName(txdata.getBondName()).setBondId(txdata.getBondId()).setStartData(startData).setEndData(endData));
                }
            });

            incrNewYearList.sort((a, b) -> new CompareToBuilder().append(a.getYear(), b.getYear()).toComparison());
            incrNewYearList.forEach(ia -> {
                ia.calcIncr();
                System.out.println(StrUtil.format("{},{},{},{},{}", ia.getBondId(), ia.getBondName(), ia.getYear(), ia.getFirstDate(), ia.getIncr()));
            });
        }


        //计算平均值
        Map<String, List<IncrNewYear>> incrMap = incrNewYearList.stream().collect(Collectors.groupingBy(IncrNewYear::getBondName));
        incrMap.forEach((k, v) -> {

            IncrNewYear incrNewYear = v.get(0);

            BigDecimal sum = v.stream().map(IncrNewYear::getIncr).reduce(BigDecimal.ZERO, BigDecimal::add);
            // 计算列表的大小
            int size = v.size();
            // 计算平均值
            BigDecimal average = sum.divide(new BigDecimal(size), 3, BigDecimal.ROUND_HALF_UP);

            // 输出结果

            System.out.println(StrUtil.format("{}-{},{}年以来平均值,{}", incrNewYear.getBondId(), incrNewYear.getBondName(), size, average));
        });


    }
}
